package com.bestcem.xm.award.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.bestcem.xm.award.constant.RedisKeyConstant;
import com.bestcem.xm.award.controller.dto.draw.AwardRequestDayStatsDTO;
import com.bestcem.xm.award.dao.AwardRequestDao;
import com.bestcem.xm.award.lua.IncreaseAwardRequestCountLua;
import com.bestcem.xm.award.service.AwardCountRequestCacheService;
import com.bestcem.xm.award.service.dto.awardaward.GetRequestStatsDTO;
import com.bestcem.xm.componet.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 奖励请求数量缓存辅助类
 *
 * @author sh.pei <sh.pei@idiaoyan.com>
 * @version v1.0
 * @date 2021/11/14 2:48
 */
@Slf4j
@Service
public class AwardCountRequestCacheServiceImpl implements AwardCountRequestCacheService {


    @Autowired
    private IncreaseAwardRequestCountLua increaseAwardRequestCountLua;

    @Autowired
    private RedisService redisService;

    //@Autowired
    //private AwardAwardDao awardAwardDao;

    @Autowired
    private AwardRequestDao awardRequestDao;

    @Override
    public void initRequestCount(String awardId, int total, int pass) {
        String key = String.format(RedisKeyConstant.AWARD_COUNT_REQUEST, awardId);
        HashMap<String, String> map = new HashMap<>();
        map.put("total", String.valueOf(total));
        map.put("pass", String.valueOf(pass));
        redisService.hashSetAll(key, map);
    }

    @Override
    public void delRequestCount(String awardId) {
        String key = String.format(RedisKeyConstant.AWARD_COUNT_REQUEST, awardId);
        redisService.del(key);
    }

    @Override
    public void addRequestCount(String awardId, int total, int pass) {
        String requestKey = String.format(RedisKeyConstant.AWARD_COUNT_REQUEST, awardId);
        String today = DateUtil.format(new Date(), DatePattern.NORM_DATE_FORMAT);
        String requestDayKey = String.format(RedisKeyConstant.AWARD_COUNT_DAY_REQUEST, awardId, today);
        Object ret = redisService.execute(increaseAwardRequestCountLua.getRedisScript(), Arrays.asList(requestKey, requestDayKey), total, pass);
        if (ret == null || (Long) ret != 1) {
            GetRequestStatsDTO getRequestStatsDTO = awardRequestDao.getRequestCount(awardId, null);
            initRequestCount(awardId, getRequestStatsDTO.getTotalCount() != null ? getRequestStatsDTO.getTotalCount() : 0, getRequestStatsDTO.getPassCount() != null ? getRequestStatsDTO.getPassCount() : 0);
        }
    }

    @Override
    public long[] getRequestTotalAndPassCount(String awardId) {
        String key = String.format(RedisKeyConstant.AWARD_COUNT_REQUEST, awardId);
        Map<Object, Object> map = redisService.hashGetAll(key);
        long[] ret = new long[2];

        if (map.containsKey("total") && map.containsKey("pass")) {
            ret[0] = Long.parseLong(String.valueOf(map.get("total")));
            ret[1] = Long.parseLong(String.valueOf(map.get("pass")));
        } else {
            GetRequestStatsDTO getRequestStatsDTO = awardRequestDao.getRequestCount(awardId, null);
            ret[0] = getRequestStatsDTO.getTotalCount() == null ? 0 : getRequestStatsDTO.getTotalCount();
            ret[1] = getRequestStatsDTO.getPassCount() == null ? 0 : getRequestStatsDTO.getPassCount();
        }
        return ret;
    }

    @Override
    public List<AwardRequestDayStatsDTO> getRequestTotalAndPassDayCount(String awardId, Date startDay, int dayMax) {
        List<AwardRequestDayStatsDTO> list = new ArrayList<>();
        AwardRequestDayStatsDTO awardRequestDayStatsDTO;
        for (int i = 0; i <= dayMax; i++) {
            Date date = DateUtil.offset(startDay, DateField.DAY_OF_YEAR, i).toJdkDate();
            //将时分秒置0
            date = com.bestcem.xm.common.core.uitls.DateUtil.getYearMonthDay(date);
            String day = DateUtil.formatDate(date);
            String requestDayKey = String.format(RedisKeyConstant.AWARD_COUNT_DAY_REQUEST, awardId, day);
            Map<Object, Object> map = redisService.hashGetAll(requestDayKey);
            awardRequestDayStatsDTO = new AwardRequestDayStatsDTO();
            awardRequestDayStatsDTO.setDay(day);
            if (map.containsKey("total") && map.containsKey("pass")) {
                awardRequestDayStatsDTO.setTotal(Integer.valueOf(String.valueOf(map.get("total"))));
                awardRequestDayStatsDTO.setPass(Integer.valueOf(String.valueOf(map.get("pass"))));
            } else {
                GetRequestStatsDTO requestCountDay = awardRequestDao.getRequestCountDay(awardId, null, date);
                HashMap<String, String> putMap = new HashMap<>();
                putMap.put("total", String.valueOf(requestCountDay.getTotalCount() != null ? requestCountDay.getTotalCount() : 0));
                putMap.put("pass", String.valueOf(requestCountDay.getPassCount() != null ? requestCountDay.getPassCount() : 0));
                redisService.hashSetAll(requestDayKey, putMap);
                redisService.expire(requestDayKey, 172800, TimeUnit.SECONDS);
                awardRequestDayStatsDTO.setTotal(requestCountDay.getTotalCount() != null ? requestCountDay.getTotalCount() : 0);
                awardRequestDayStatsDTO.setPass(requestCountDay.getPassCount() != null ? requestCountDay.getPassCount() : 0);
            }
            list.add(awardRequestDayStatsDTO);
        }
        return list;
    }

    /*@Override
    public ServiceResult<String> initAwardsRequestCount() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
        List<AwardAwardDO> awardAwards = awardAwardDao.listAwardAwardByQdesIdAndStatus(null, null, Arrays.asList(AwardStatusEnum.INACTIVE.getIndex(), AwardStatusEnum.ACTIVE.getIndex(), AwardStatusEnum.FINISH.getIndex(), AwardStatusEnum.PAUSE.getIndex()));
        if (CollectionUtils.isEmpty(awardAwards)) {
            log.info("[award] 初始化奖励请求数据，没有奖励请求数据");
        }
        for (AwardAwardDO awardAward : awardAwards) {
            threadPoolExecutor.execute(() -> {
                GetRequestStatsDTO getRequestStatsDTO = awardRequestDao.getRequestCount(awardAward.getId(), null);
                initRequestCount(awardAward.getId(), getRequestStatsDTO.getTotalCount() != null ? getRequestStatsDTO.getTotalCount() : 0, getRequestStatsDTO.getPassCount() != null ? getRequestStatsDTO.getPassCount() : 0);
                Date now = new Date();
                // 最近7天缓存
                for (int i = -6; i <= 0; i++) {
                    Date date = DateUtil.offsetDay(now, i).toJdkDate();
                    String day = DateUtil.formatDate(date);
                    GetRequestStatsDTO requestCountDay = awardRequestDao.getRequestCountDay(awardAward.getId(), null, date);
                    String requestDayKey = String.format(RedisKeyConstant.AWARD_COUNT_DAY_REQUEST, awardAward.getId(), day);
                    HashMap<String, String> map = new HashMap<>();
                    map.put("total", String.valueOf(requestCountDay.getTotalCount() != null ? requestCountDay.getTotalCount() : 0));
                    map.put("pass", String.valueOf(requestCountDay.getPassCount() != null ? requestCountDay.getPassCount() : 0));
                    redisService.hashSetAll(requestDayKey, map);
                }
            });
        }
        while (threadPoolExecutor.getActiveCount() > 0) {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return ServiceResult.success();
    }*/
}
